<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- 添加视口元标签 -->
<title>在不受限/受限条件下的弥散运动模拟by吴宁</title>
<style>
  body {
    display: flex;
    flex-direction: column;
    align-items: center; /* 居中显示画布和按钮 */
    margin: 0;
    padding: 0;
  }
  canvas {
    border: 1px solid #ddd;
    display: block; /* 使画布元素垂直堆叠 */
    margin-bottom: 20px; /* 在画布之间添加一些空间 */
    /* 适配屏幕宽度，但不超过400px */
    max-width: 100%;
    height: auto;
  }
  button {
    font-size: 16px; /* 适当调整字体大小 */
    padding: 10px 20px; /* 增加内边距，使按钮更大 */
    margin: 10px; /* 增加外边距 */
    cursor: pointer; /* 鼠标悬停时显示指针光标 */
  }
  /* 可以添加更多的媒体查询来针对不同屏幕大小进行优化 */
  @media (max-width: 600px) {
    button {
      font-size: 14px;
    }
  }
</style>
</head>
<body>

<canvas id="rectCanvas" width="400" height="300"></canvas>
<canvas id="circleCanvas" width="400" height="300"></canvas>
<button onclick="startAnimation()">开始</button>
<button onclick="pauseAnimation()">暂停</button>

<script>
let timeoutIdRect, timeoutIdCircle;
const delay = 50; // 控制运动速度

// 初始化粒子
let particleRect = { x: 200, y: 200, oldX: 200, oldY: 200 };
let particleCircle = { x: 200, y: 200, oldX: 200, oldY: 200 };

const rectCanvas = document.getElementById('rectCanvas');
const rectContext = rectCanvas.getContext('2d');
const circleCanvas = document.getElementById('circleCanvas');
const circleContext = circleCanvas.getContext('2d');

const circleX = circleCanvas.width / 2;
const circleY = circleCanvas.height / 2;
const circleRadius = circleCanvas.width / 4;

// 绘制初始边界
// drawBoundaryRect();
drawBoundaryCircle();

function drawBoundaryRect() {
  rectContext.strokeStyle = '#000';
  rectContext.strokeRect(0, 0, rectCanvas.width, rectCanvas.height);
}

function drawBoundaryCircle() {
  circleContext.beginPath();
  circleContext.strokeStyle = '#000';
  circleContext.arc(circleX, circleY, circleRadius, 0, Math.PI * 2);
  circleContext.stroke();
}

function drawParticle(particle, context) {
  // Draw trail
  context.strokeStyle = 'gray';
  context.lineWidth = 1;
  context.beginPath();
  context.moveTo(particle.oldX, particle.oldY);
  context.lineTo(particle.x, particle.y);
  context.stroke();

  // Draw particle
  context.fillStyle = 'red';
  context.beginPath();
  context.arc(particle.x, particle.y, 2.5, 0, Math.PI * 2);
  context.fill();
}

function isInCircle(x, y) {
  const dx = x - circleX;
  const dy = y - circleY;
  return Math.sqrt(dx * dx + dy * dy) < circleRadius;
}

function updateParticlePosition(particle, context, canvas, shape) {
  let newX, newY;
  if (shape === 'circle') {
    do {
      const angle = Math.random() * 2 * Math.PI; // Full circle
      const stepSize = 60; // Adjust step size for visualization
      newX = particle.x + Math.cos(angle) * stepSize;
      newY = particle.y + Math.sin(angle) * stepSize;
    } while (!isInCircle(newX, newY));
  } else { // Rectangle
    const angle = Math.random() * 2 * Math.PI; // Full circle
    const stepSize = 60; // Adjust step size for visualization
    newX = particle.x + Math.cos(angle) * stepSize;
    newY = particle.y + Math.sin(angle) * stepSize;
    // Check and handle boundary collisions for rectangle
    if (newX <= 0 || newX >= canvas.width) {
      newX = particle.x; // Revert to old position
    }
    if (newY <= 0 || newY >= canvas.height) {
      newY = particle.y; // Revert to old position
    }
  }

  particle.oldX = particle.x;
  particle.oldY = particle.y;
  particle.x = newX;
  particle.y = newY;
}

function animateRect() {
  updateParticlePosition(particleRect, rectContext, rectCanvas, 'rect');
  drawParticle(particleRect, rectContext);
  timeoutIdRect = setTimeout(animateRect, delay);
}

function animateCircle() {
  updateParticlePosition(particleCircle, circleContext, circleCanvas, 'circle');
  drawParticle(particleCircle, circleContext);
  timeoutIdCircle = setTimeout(animateCircle, delay);
}

function startAnimation() {
  if (!timeoutIdRect && !timeoutIdCircle) {
    animateRect();
    animateCircle();
  }
}

function pauseAnimation() {
  clearTimeout(timeoutIdRect);
  clearTimeout(timeoutIdCircle);
  timeoutIdRect = null;
  timeoutIdCircle = null;
}
</script>
</body>
</html>
